namespace ScrumSprintMonitor.Implementation
{
	#region #using Directives

	using System;
	using System.Linq;

	using Infrastructure;
	using Infrastructure.Configuration;

	#endregion

	public class RemainingWorkStatusEvaluator : IRemainingWorkStatusEvaluator
	{
		private readonly IPresentationConfiguration presentationConfiguration;

		private readonly RemainingWorkStatus[] statusRange = new[]
		                                                     	{
		                                                     		RemainingWorkStatus.SeverelyUnderassigned, RemainingWorkStatus.Underassigned,
		                                                     		RemainingWorkStatus.Normal, RemainingWorkStatus.Warning, RemainingWorkStatus.Overassigned,
		                                                     		RemainingWorkStatus.SeverelyOverassigned
		                                                     	};

		public RemainingWorkStatusEvaluator(IPresentationConfiguration presentationConfiguration)
		{
			this.presentationConfiguration = presentationConfiguration;
		}

		#region IRemainingWorkStatusEvaluator Members

		public RemainingWorkStatus Evaluate(double remainingWork, double availableTime)
		{
			double ratio = remainingWork / Math.Max(0, availableTime);

			if (ratio == 0.0 || remainingWork == 0.0)
			{
				return RemainingWorkStatus.NoWorkLeft;
			}

			if (double.IsNaN(ratio))
			{
				if (availableTime <= 0.0)
				{
					return RemainingWorkStatus.SeverelyOverassigned;
				}
			}

			if (double.IsNaN(remainingWork))
			{
				return RemainingWorkStatus.SeverelyOverassigned;
			}

			return this.statusRange.First(status => RatioIsWithinStatusRange(ratio, status));
		}

		#endregion

		private bool RatioIsWithinStatusRange(double ratio, RemainingWorkStatus status)
		{
			var configuration = this.presentationConfiguration.GetRemainingWorkStatusPresentationConfig(status);

			return (ratio > configuration.LowerLimit && ratio <= configuration.UpperLimit);
		}
	}
}